/*
 * Copyright 2019 成都深地领航能源科技有限公司. All rights reserved.
 * PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.sdlh.demo.socket;

import com.sdlh.demo.springboot.po.RecordPO;
import com.sdlh.demo.springboot.service.RecordService;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author 成都深地领航能源科技有限公司
 */
@Slf4j
public class Server {
    private ServerSocket serverSocket;
    private RecordService recordService;

    public static void main(String[] args) {
//        new Server().init();
    }

    public void init(RecordService recordService, int port) {
        try {
            this.recordService = recordService;
            serverSocket = new ServerSocket(port);
            log.info("服务器端socket启动...");
            Socket socket = serverSocket.accept();
            log.info("客户端:"+socket.getInetAddress().getLocalHost()+"已连接到服务器");
            List<String> list = null;
            StringBuilder builder = new StringBuilder();
            InputStream in = socket.getInputStream();
            byte[] buf = new byte[2048];
            try {
                while (in.read(buf) > 0) {
                    //读取客户端发送来的消息
                    String msg = new String(buf).trim();
                    System.out.println();
                    log.info("收到客户端wits消息:");
                    Stream.of(msg.split(" "))
                          .forEach(s -> {
                              builder.append(asciiToString(s));
                          });
                    System.out.println(builder);
                    list = new ArrayList<>(Arrays.asList(builder.toString().split("\r\n")));
                    builder.setLength(0);
                    log.info("解析得到数据集:");
                    parseRecord(list);
                    list.clear();
                    clear(buf);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            log.info("客户端socket断开，关闭serversocket");
            close(socket);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解析record数据
     *
     * @param list
     */
    public void parseRecord(List<String> list) {
        for (int i = 0; i < list.size(); i++) {
            if ("&&".equals(list.get(i)) || "!!".equals(list.get(i))) {
                continue;
            }

            String msg =  list.get(i);
//            log.info("record:" + msg);
            int table = Integer.parseInt(msg.substring(0,2));
            int item = Integer.parseInt(msg.substring(2,4));
            RecordPO record = recordService.findItem(item, table);
            log.info(record.getDesc_en() + "[" + record.getLongmnemonic() + "]:"
                    + msg.substring(4) + " " + (record.getMetricunits() == null ? "" : record.getMetricunits()));
        }
    }

    /**
     * 清空缓存字节数组
     */
    public void clear(byte[] buf) {
        for (int i = 0; i < buf.length; i++) {
            buf[i] = 0;
        }
    }
    /**
     * 将16进制 ASCII转成字符串
     *
     * @param hexValue
     * @return
     */
    public String asciiToString(String hexValue) {
        StringBuffer sbu = new StringBuffer();
        for (int i = 0; i < hexValue.length(); i += 2) {
            sbu.append((char) Integer.parseInt(hexValue.substring(i, i + 2), 16));
        }
        return sbu.toString();
    }

    public void write(Socket socket) throws IOException {
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        new Thread(() -> {
            try {
                while (true) {
                    Thread.sleep(2000);
                    log.info("心跳检测");
                    bw.write("heart beat!\n");
                    bw.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
                log.info("心跳检测失败，关闭serversocket");
                close(socket);
            }
        }).start();
    }

    public void close(Socket socket) {
        try {
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
